package com.seed.core.query;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.seed.core.action.Action;
import com.seed.core.configuration.*;
import com.seed.core.converter.ActionConverter;
import com.seed.core.pojo.seed.Seed;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class App extends Micro {
    private final AppConfiguration configuration;
    private Map<String, Micro> micros;

    public App(AppConfiguration configuration) {
        this.configuration = configuration;
    }

    public void setMicros(Map<String, Micro> micros) {
        this.micros = micros;
    }

    public Micro getMicro(String microName) {
        if(StrUtil.isBlank(microName)) return this;

        Micro micro = micros.get(microName);
        if(micro == null) throw new RuntimeException(String.format("服务【%s】不存在", microName));

        return micro;
    }

    public boolean existMicro(String microName) {
        Map<String, MicroConfiguration> micros = getConfigurationMicros();
        return micros != null && micros.containsKey(microName);
    }

    public String getOwner() {
        return configuration.getOwner();
    }

    public String getName() {
        return configuration.getName();
    }

    public Map<String, Seed> getConfigurationSeeds() {
        return getConfigurationSeeds(configuration);
    }

    public Map<String, Seed> getConfigurationSeeds(String microName) {
        Map<String, MicroConfiguration> micros = configuration.getMicros();
        if(micros == null) return Collections.emptyMap();

        MicroConfiguration micro = micros.get(microName);
        if(micro == null) return Collections.emptyMap();

        return getConfigurationSeeds(micro);
    }

    private Map<String, Seed> getConfigurationSeeds(MicroConfiguration micro) {
        Map<String, Seed> ret = new HashMap<>();
        Map<String, SeedConfiguration> seeds = micro.getSeeds();
        if(seeds == null) return ret;

        for(Map.Entry<String, SeedConfiguration> entry: seeds.entrySet()) {
            ret.put(entry.getKey(), entry.getValue().toSeed());
        }
        return ret;
    }

    public Map<String, Action> getConfigurationActions() {
        return getConfigurationActions(configuration);
    }

    private Map<String, Action> getConfigurationActions(MicroConfiguration configuration) {
        Map<String, Action> ret = new HashMap<>();
        Map<String, ActionConfiguration1> actions = configuration.getActions();
        if(actions == null) return ret;

        for(Map.Entry<String, ActionConfiguration1> entry: actions.entrySet()) {
            ret.put(entry.getKey(), ActionConverter.toAction(entry.getValue()));
        }

        return ret;
    }

    public Map<String, Action> getConfigurationActions(String microName) {
        Map<String, MicroConfiguration> micros = configuration.getMicros();
        if(micros == null) return Collections.emptyMap();

        MicroConfiguration micro = micros.get(microName);
        if(micro == null) return Collections.emptyMap();

        return getConfigurationActions(micro);
    }

    public List<String> getConfigurationLibs() {
        String[] libs = configuration.getLibs();
        return libs == null ? Collections.emptyList() : List.of(libs);
    }

    public List<String> getConfigurationLibs(String microName) {
        if(StrUtil.isBlank(microName)) return getConfigurationLibs();

        Map<String, MicroConfiguration> micros = configuration.getMicros();
        if(micros == null) return Collections.emptyList();

        MicroConfiguration micro = micros.get(microName);
        if(micro == null) return Collections.emptyList();

        String[] libs = micro.getLibs();
        return libs == null ? Collections.emptyList() : List.of(libs);
    }

    public Map<String, MicroConfiguration> getConfigurationMicros() {
        return configuration.getMicros();
    }

    public AppConfiguration getConfiguration() {
        return configuration;
    }
}
